import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { ScenarioService } from './scenario.service';
import { CreateScenarioDto } from './dto/create-scenario.dto';
import { UpdateScenarioDto } from './dto/update-scenario.dto';
import { Api } from 'src/utils/api';
import { SwaggerOk } from 'src/decorators/swagger.decorator';
import { API_CODES, API_MSGS } from 'src/const/api.const';
import { PagerDto } from 'src/dto/api.dto';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { getSkipAndTake } from 'src/utils/func';
import { FeatureScenarioService } from 'src/feature-scenario/feature-scenario.service';
 

@ApiTags('scenario接口')
@Controller('scenario')
export class ScenarioController {
  constructor(
    private readonly scenarioService: ScenarioService,
    private fsService:FeatureScenarioService
    ) {}

  
  @ApiOperation({summary:'创建scenario'})
  @Post()
  @SwaggerOk()
  async create(@Body() payload: CreateScenarioDto) {
    const data = await this.scenarioService.findOneByScenario(payload.scenario);
    if(data != null){
      return Api.err(API_CODES.SCENARIO_EXIST,  API_MSGS[API_CODES.SCENARIO_EXIST] )
    }
    const {scenario, description, beforeAction, fid } = payload;
    const res = await  this.scenarioService.create({ scenario, description});

    if(beforeAction){
      // 如果当前操作是前置操作, 那么设定前置操作
      this.scenarioService.setPreActions(res.id);
    }

    if(fid>0){
      // 创建当前scenario和feature的关联关系
      this.fsService.create({
        fid:fid,
        sid:res.id
      })
    }

    return Api.ok(res)
  }

  @Get()
  @SwaggerOk()
  async findAll() {
    const data = await this.scenarioService.findAll();
    return Api.ok(data)
  }

  @ApiOperation({summary:'根据分页查询scenario数据'})
  @Post('/All')
  async fildAllByPages(@Body() data:PagerDto){
    const { page, pageSize } = data;
    const {take, skip } = getSkipAndTake(page, pageSize);
    const total = await this.scenarioService.findTotal();
    const res =await this.scenarioService.findByPages(skip, take);
    return Api.pagerOk({
      data:res,
      page,
      pageSize,
      total
    });
  }

  @ApiOperation({summary:'根据scenario名称或者描述模糊查询'})
  @Get('/search/:key')
  async searchByKey(@Param('key') key: string) {
    // 查询单个Scenario数据
    const data = await this.scenarioService.searchByKey(key);
    return Api.ok(data)
  }

  @Get(':id')
  async findOne(@Param('id') id: string) {
    // 查询单个Scenario数据
    const data =await this.scenarioService.findOne(+id);
     const res = {
      id:data.id, 
      scenario:data.scenario, 
      description:data.description,
      beforeAction: data.preActions != null ? true : false
    }

    return Api.ok(res);
  }

  @ApiOperation({summary:"查询所有的前置操作"})
  @Get('/preActions/All')
  async findPreActions(){
    // console.log("查询所有的前置操作");
    const data = await this.scenarioService.getPreactions();
    return Api.ok(data);
  }



  @ApiOperation({summary:'更新操作'})
  @Patch(':id')
  async update(@Param('id') id: string, @Body() payload: UpdateScenarioDto) {
    const { beforeAction } = payload;
    if(beforeAction){
      // 
      await this.scenarioService.setPreActions(+id);
    }else{
      await this.scenarioService.removePreactions(+id);
    }
    delete payload.beforeAction

    await this.scenarioService.update(+id, payload);
    return Api.ok()
  }

  @Delete('')
  @SwaggerOk()
  async remove(@Query() query ) {
    const {fid, sid } = query;
    // 先查询feature-scenario中间表中是否关联了feature, 如果有, 先给出提示信息
    const datas = await this.fsService.findManyBySid(+sid);
    // console.log("datas---", datas);
    const relations = new Set();
    datas.map( d=>{
      if(d.fid !== +fid){
        relations.add(d.feature.feature)
      }
    });

    // console.log("relations---", relations);
    if(relations.size>0){
      const content = Array.from(relations).join(",")
      return Api.err(API_CODES.SCENARIO_RELATED_FEATURE,  
         `本Scenario关联了如下feature: ${content},无法删除`
        )
    }else{
      // console.log("可以删除---");
      // 先移除关联关系
      await this.fsService.remove(+fid, +sid);
      // 再移除scenario下的cases和scenario
      await this.scenarioService.remove(+sid);
      return Api.ok()
    }
  }

  @ApiOperation({summary:'复制scenario和cases'})
  @Get('/copy/:id')
  async copy(@Param('id') id: string ){
    await this.scenarioService.copy(+id);
    return Api.ok();
  }

}
